Param (
    [Parameter(Mandatory=$false)] [int16]$Days = 14,
    [Parameter(Mandatory=$false)] [string]$SortBy = "UserName",
    [Parameter(Mandatory=$false)] [switch]$Desc
)

Write-Output "Usage (in admin's powershell): .\ListNotUsed.ps1 [-Days {int}] [-SortBy {UserName|ProfilePath|LastUsedDate|FolderSize} [-Desc]]"
Write-Output "Defaults: Days=14, SortBy=UserName, sorted in ascending.`n"

Write-Host "Checking for elevated permissions..."
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Warning "Insufficient permissions to run this script. Open the PowerShell console as an administrator and run this script again.`n"
    pause
    Break
    # Start-Process Powershell -ArgumentList $PSCommandPath -Verb RunAs
}else{
    Write-Output "Permissions are OK.`n"
}

Write-Output "Finding profiles which older then $Days days ..." 

$allprofilesinfo = @()
# Получение объектов (профилей) через вызов Get-WMIObject (которые не специальные и не зарегистрированны сейчас, и регистрировались более $days дней назад):
$OldProfiles = Get-WMIObject -Class Win32_UserProfile | Where-Object {(!$_.Special) -and (!$_.Loaded) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-$Days))}

# Вариант получения объектов (профилей) через вызов Get-CIMInstance (это "более перспективно" и, например, позволяет использовать напрямую параметр -ComputerName $compname):  
# $OldProfiles = Get-CimInstance -ClassName Win32_UserProfile | Where-Object {(!$_.Special) -and (!$_.Loaded) -and ($_.LastUseTime -lt (Get-Date).AddDays(-$Days))}

$OldProfilesCount = $OldProfiles.Count
Write-Output "Number of founded profiles: $OldProfilesCount"

# Если найдены профили, отвечающие условиям:
if ($OldProfilesCount -gt 0) {
    # Включение индикатора прогресса выполнения:
    $i = 0
    $progress = @{
        Activity = "Count profiles disk usage summary..."
        CurrentOperation = "Collect data"
        PercentComplete = $i
    }
    [double]$FolderSizeTotal = 0
    foreach ($OldProfile in $OldProfiles) {
        $objSID = New-Object System.Security.Principal.SecurityIdentifier ($OldProfile.SID)
        $objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
        $userinfo = New-Object PSObject -Property @{
            UserName = $objUser.Value
            ProfilePath = $OldProfile.localpath
            LastUsedDate = $OldProfile.ConvertToDateTime($OldProfile.LastUseTime)
            FolderSize =  "{0:N2} GB" -f ((Get-ChildItem -force $OldProfile.localpath -Recurse -ErrorAction SilentlyContinue| Measure-Object Length -s).sum / 1Gb) 
        }
        # Подсчёт общего занимаемого объема (обратное преобразование в тип double):
        $FolderSizeTotal += [double]::Parse($($userinfo.FolderSize).Substring(0, $($userinfo.FolderSize).IndexOf(" ")))

        $allprofilesinfo += $userinfo

        # Обновление индикатора прогресса выполнения:
        $i++
        [int]$percentage = ($i / $OldProfilesCount) * 100
        $progress.CurrentOperation = $userinfo.UserName
        $progress.PercentComplete = $percentage
        Write-Progress @progress
    }

    $messagestr = "Result (sorted by '$SortBy'"
    # Если в функцию передан параметр -Desc ("сортировака в обратном порядке"),
    if ($Desc) {
        $allprofilesinfo = ($allprofilesinfo | Sort-Object $sortby -Descending)
        $messagestr += " in descending order"
    }else{
        $allprofilesinfo = ($allprofilesinfo | Sort-Object $sortby)
    }
    
    Write-Output "$messagestr):"
    # ($allprofilesinfo | Sort-Object $sortby) 
    foreach ($OneProfile in $allprofilesinfo) {
        Write-Output $OneProfile
    }
    $messagestr = "Total size of these profiles' folders:$("`t" * 5)  $FolderSizeTotal GB"
    # Строка из символов "-"
    Write-Output $("-" * ($messagestr.Length + 36))
    Write-Output $messagestr
}

#
# END OF SCRIPT
# Write-Host "."
# Read-Host -Prompt "Press ENTER to continue"
# cmd /c 'pause'
# [Console]::ReadKey()